#include "StdAfx.h"
#include <Windows.h>
#include "Console.h"


using namespace MoeWare;
using namespace Ogre;
using namespace OgreMax;

template<> Console* Ogre::Singleton<Console>::ms_Singleton = NULL;

Console::Console(const String defaultTitle):
_PluginsFilePath("Plugins.cfg"),
_ConfiguresFilePath("MoeWare.cfg"),
_ResourcesFilePath("Resources.cfg"),
_LogFilePath("MoeWare.log")
{
	OGRE_NEW LogManager();
	LogManager::getSingleton().createLog(this->_LogFilePath, true, true, false);
	LogManager::getSingleton().getDefaultLog()->setDebugOutputEnabled(true);

	OGRE_NEW Root(this->_PluginsFilePath, this->_ConfiguresFilePath);
	//Root::getSingleton().restoreConfig();
	Root::getSingleton().showConfigDialog();
	Root::getSingleton().initialise(true, defaultTitle);

	HWND hWnd;
	Root::getSingleton().getAutoCreatedWindow()->getCustomAttribute("WINDOW", &hWnd);
	OIS::InputManager* inputManager = OIS::InputManager::createInputSystem((size_t)hWnd);

	this->InitialResourceManager();

	//NxPhysicsSDK* sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
	NxGetPhysicsSDK()->setParameter(NX_SKIN_WIDTH, 0.025f);
	NxGetPhysicsSDK()->setParameter(NX_VISUALIZATION_SCALE, 1.0f);
	NxGetPhysicsSDK()->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1.0f);

	//NxRemoteDebugger* debugger = NxGetPhysicsSDK()->getFoundationSDK().getRemoteDebugger();
	//debugger->connect("localhost");
	//this->temp();
	this->LoadOgreMaxTest();
	this->LoadPhysXTest();

	this->_PhysXDebugRender = Root::getSingleton().getSceneManager("SceneManagerInstance1")->createManualObject("PhysXDebugRender");
	Root::getSingleton().getSceneManager("SceneManagerInstance1")->getRootSceneNode()->createChildSceneNode()->attachObject(this->_PhysXDebugRender);


	Root::getSingleton().addFrameListener(this);
	//Root::getSingleton().startRendering();
}


Console::~Console(void)
{
	//NxReleasePhysicsSDK(NxGetPhysicsSDK());
	Root::getSingleton().shutdown();
	OGRE_DELETE Root::getSingletonPtr();
	OGRE_DELETE LogManager::getSingletonPtr();
}

void Console::InitialResourceManager()
{
    Ogre::String secName, typeName, archName;
    Ogre::ConfigFile cf;
	cf.load(this->_ResourcesFilePath);

    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
			OgreMaxScene::ResourceLocation resourceLocation(archName, typeName);
			this->_OgreMaxScene.AddResourceLocation(resourceLocation);
        }
    }
	this->_OgreMaxScene.CommitResourceLocations();
}
void Console::temp()
{
	Root::getSingleton().createSceneManager(ST_GENERIC, "DefaultSceneManager");
	Root::getSingleton().getSceneManager("DefaultSceneManager")->setAmbientLight(ColourValue::White);

	Root::getSingleton().getSceneManager("DefaultSceneManager")->createCamera("DefaultCamera");
	Root::getSingleton().getSceneManager("DefaultSceneManager")->getCamera("DefaultCamera")->setPosition(0.0f, 60.0f, 100.0f);
	Root::getSingleton().getSceneManager("DefaultSceneManager")->getCamera("DefaultCamera")->lookAt(0.0f, 0.0f, 0.0f);
	Root::getSingleton().getSceneManager("DefaultSceneManager")->getCamera("DefaultCamera")->setNearClipDistance(1.0f);
	Root::getSingleton().getSceneManager("DefaultSceneManager")->getCamera("DefaultCamera")->setAutoAspectRatio(true);

	Root::getSingleton().getAutoCreatedWindow()->addViewport(Root::getSingleton().getSceneManager("DefaultSceneManager")->getCamera("DefaultCamera"));
	Root::getSingleton().getAutoCreatedWindow()->getViewport(0)->setBackgroundColour(ColourValue::Blue);
	Root::getSingleton().getAutoCreatedWindow()->setActive(true);

    Ogre::String secName, typeName, archName;
    Ogre::ConfigFile cf;
	cf.load(this->_ResourcesFilePath);

    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
        }
    }
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();


Ogre::Entity* ogreHead = Root::getSingleton().getSceneManager("DefaultSceneManager")->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = Root::getSingleton().getSceneManager("DefaultSceneManager")->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
}

void Console::LoadOgreMaxTest()
{
	
	this->_OgreMaxScene.Load("scene.scene", Root::getSingleton().getAutoCreatedWindow());

	this->_OgreMaxScene.Update(0.1f);
	Ogre::SceneManagerEnumerator::SceneManagerIterator iterator = Root::getSingleton().getSceneManagerIterator();
	iterator.begin();
	while(iterator.hasMoreElements())
	{
		String key = iterator.peekNextKey();
		iterator.moveNext();
	}
	Root::getSingleton().getAutoCreatedWindow()->addViewport(Root::getSingleton().getSceneManager("SceneManagerInstance1")->getCamera("Camera01"));
	Root::getSingleton().getAutoCreatedWindow()->getViewport(0)->setBackgroundColour(ColourValue::Blue);
	Root::getSingleton().getAutoCreatedWindow()->setActive(true);
}

void Console::LoadPhysXTest()
{
	//C:\Program Files\NVIDIA Corporation\NVIDIA PhysX SDK\v2.8.4_win\Samples\Media\test.dae
	
	//this->_PhysicsCollection = NXU::loadCollection("C:\\Program Files\\NVIDIA Corporation\\NVIDIA PhysX SDK\\v2.8.4_win\\Samples\\Media\\test.nxb", NXU::FT_BINARY);
	this->_PhysicsCollection = NXU::loadCollection("C:\\Program Files\\NVIDIA Corporation\\NVIDIA PhysX SDK\\v2.8.4_win\\Bin\\win32\\SceneSave0.nxb", NXU::FT_BINARY);
	NxMat34 root;
	NXU::instantiateCollection(this->_PhysicsCollection, *NxGetPhysicsSDK(), NULL, &root, NULL);
	//NXU::releaseCollection(this->_PhysicsCollection);

	NxGetPhysicsSDK()->getScene(0)->simulate(0.0f);
}

bool Console::frameStarted(const FrameEvent& evt)
{
	NxGetPhysicsSDK()->getScene(0)->fetchResults(NxSimulationStatus::NX_ALL_FINISHED, true);
	return FrameListener::frameStarted(evt);
}

bool Console::frameRenderingQueued(const FrameEvent& evt)
{
	int ii = NxGetPhysicsSDK()->getNbScenes();
	NxScene* physXScene = NxGetPhysicsSDK()->getScene(0);
	const NxDebugRenderable* debugData =  physXScene->getDebugRenderable();
	this->_PhysXDebugRender->clear();
	PhysicsSystem::getSingleton().DrawDebugScene(physXScene, this->_PhysXDebugRender);
	NxGetPhysicsSDK()->getScene(0)->simulate(evt.timeSinceLastFrame);
	return FrameListener::frameRenderingQueued(evt);
}

bool Console::frameEnded(const FrameEvent& evt)
{
	return false;
	return FrameListener::frameEnded(evt);
}
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
{
	try
	{
		Console* console = OGRE_NEW Console("MoeWare");
		Root::getSingleton().startRendering();
		OGRE_DELETE console;
	}
	catch(Exception& e)
	{
		MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR| MB_TASKMODAL);
	}
	return 0;
}